package com.fau.wm.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Hibernate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fau.wm.entity.MedicalKeyValue;
import com.fau.wm.entity.MedicalRecallDetail;
import com.fau.wm.entity.MedicalStorageDetail;
import com.fau.wm.service.IStatisticsManagerService;
import com.fau.wm.util.Page;
import com.fau.wm.util.ParamUtil;
import com.fau.wm.util.SystemConfig;

@Service
@Transactional(readOnly = true)
public class StatisticsManagerService extends BaseService implements IStatisticsManagerService {

	private String formatParam(String param) {
		if(null != param) {
			param = param.replaceAll("_", "chr(95)").replaceAll("%", "chr(37)");
		} else {
			param = "";
		}
		return param;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Page findStorageDetailByPage(MedicalStorageDetail storageDetail, Map<String, Object> map) {
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalStorageDetail m where m.storage.status=? and m.storage.hospitalId=? ");
		StringBuilder statusSql = new StringBuilder("from MedicalStorageDetail  m where m.storage.status=? and m.storage.hospitalId=? ");
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(SystemConfig.STORAGE_STATUS_APPROVAL);
		objectList.add(storageDetail.getHospitalId());
		
		if(StringUtils.isNotBlank(storageDetail.getSerialNum())) {
			countSql.append("and m.storage.serialNum = ? ");
			statusSql.append("and m.storage.serialNum = ? ");
			objectList.add(storageDetail.getSerialNum());
		}
		
		if(StringUtils.isNotBlank(storageDetail.getTitle())) {
			String title = this.formatParam(storageDetail.getTitle());
			countSql.append("and m.storage.title like ? ");
			statusSql.append("and m.storage.title like ? ");
			objectList.add("%"+title+"%");
		}
		
		if(null != storageDetail.getStartTime()) {
			countSql.append("and m.storage.storageTime >= ? ");
			statusSql.append("and m.storage.storageTime >= ? ");
			objectList.add(storageDetail.getStartTime());
		}
		
		if(null != storageDetail.getEndTime()) {
			countSql.append("and m.storage.storageTime <= ? ");
			statusSql.append("and m.storage.storageTime <= ? ");
			objectList.add(storageDetail.getEndTime());
		}
		
		if(StringUtils.isNotBlank(storageDetail.getWarehouseName())){
			String warehouseName = this.formatParam(storageDetail.getWarehouseName());
			countSql.append("and m.storage.warehouse.name like ? ");
			statusSql.append("and m.storage.warehouse.name like ? ");
			objectList.add("%"+warehouseName+"%");
		}
		
		if(StringUtils.isNotBlank(storageDetail.getAuditUser())){
			String auditUser = this.formatParam(storageDetail.getAuditUser());
			countSql.append("and m.storage.auditUser.name like ? ");
			statusSql.append("and m.storage.auditUser.name like ? ");
			objectList.add("%"+auditUser+"%");
		}
		
		if(StringUtils.isNotBlank(storageDetail.getMedicineNo())){
			String getMedicineNo = this.formatParam(storageDetail.getMedicineNo());
			countSql.append("and m.medicine.serialNum = ? ");
			statusSql.append("and m.medicine.serialNum = ? ");
			objectList.add(getMedicineNo);
		}
		
		if(StringUtils.isNotBlank(storageDetail.getMedicineName())){
			String medicineName = this.formatParam(storageDetail.getMedicineName());
			countSql.append("and m.medicine.name like ? ");
			statusSql.append("and m.medicine.name like ? ");
			objectList.add("%"+medicineName+"%");
		}
		
		//排序
		String[] sortField =(String[]) map.get("sortField");
		String[] sortOrder =(String[]) map.get("sortOrder");
		if(StringUtils.isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])) {
			statusSql.append("order by m.storage." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by m.createTime desc ");
		}
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		
		List<MedicalStorageDetail> list = (List<MedicalStorageDetail>) page.getResult();
		
		for (MedicalStorageDetail medicalStorageDetail : list) {
			Hibernate.initialize(medicalStorageDetail.getStorage());
			// 入库类型
			MedicalKeyValue keyValue = this.iBaseDao.getValueByKey(storageDetail.getHospitalId(), medicalStorageDetail.getStorage().getType());
			medicalStorageDetail.setStype(keyValue.getKeyValue());
			
			// 单位
			MedicalKeyValue keyValue1 = this.iBaseDao.getValueByKey(storageDetail.getHospitalId(), medicalStorageDetail.getMedicine().getUnit());
			medicalStorageDetail.setUnit(keyValue1.getKeyValue());
		}
		page.setResult(list);
		return page;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Page findRecallDetailByPage(MedicalRecallDetail recallDetail, Map<String, Object> map) {
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalRecallDetail m where m.recall.status=? and m.recall.hospitalId=? ");
		StringBuilder statusSql = new StringBuilder("from MedicalRecallDetail m where m.recall.status=? and m.recall.hospitalId=?");
		List<Object> objectList = new ArrayList<Object>();
		objectList.add("1");
		objectList.add(recallDetail.getHospitalId());
		
		if(StringUtils.isNotBlank(recallDetail.getSerialNum())){
			countSql.append("and m.recall.serialNum = ? ");
			statusSql.append("and m.recall.serialNum = ? ");
			objectList.add(recallDetail.getSerialNum());
		}
		
		if(StringUtils.isNotBlank(recallDetail.getTitle())){
			countSql.append("and m.recall.title like ? ");
			statusSql.append("and m.recall.title like ? ");
			objectList.add("%"+recallDetail.getTitle()+"%");
		}
		
		if(null != recallDetail.getStartTime()){
			countSql.append("and m.recall.recallTime >= ? ");
			statusSql.append("and m.recall.recallTime >= ? ");
			objectList.add(recallDetail.getStartTime());
		}
		
		if(null != recallDetail.getEndTime()){
			countSql.append("and m.recall.recallTime <= ? ");
			statusSql.append("and m.recall.recallTime <= ? ");
			objectList.add(recallDetail.getEndTime());
		}
		
		if(StringUtils.isNotBlank(recallDetail.getWarehouseName())){
			countSql.append("and m.recall.warehouse.name like ? ");
			statusSql.append("and m.recall.warehouse.name like ? ");
			objectList.add("%"+recallDetail.getWarehouseName()+"%");
		}
		
		if(StringUtils.isNotBlank(recallDetail.getMedicineName())){
			countSql.append("and m.medicine.name like ? ");
			statusSql.append("and m.medicine.name like ? ");
			objectList.add("%"+recallDetail.getMedicineName()+"%");
		}
		
		if(StringUtils.isNotBlank(recallDetail.getMedicineSerialNum())){
			countSql.append("and m.medicine.serialNum = ? ");
			statusSql.append("and m.medicine.serialNum = ? ");
			objectList.add(recallDetail.getMedicineSerialNum());
		}
		
		//排序
		String[] sortField =(String[]) map.get("sortField");
		String[] sortOrder =(String[]) map.get("sortOrder");
		if(StringUtils.isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])) {
			statusSql.append("order by m.recall." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by m.createTime desc ");
		}
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		
		List<MedicalRecallDetail> list = (List<MedicalRecallDetail>) page.getResult();
		
		for (MedicalRecallDetail medicalRecallDetail : list) {
			Hibernate.initialize(medicalRecallDetail.getRecall());
			
			// 出库类型
			MedicalKeyValue keyValue = this.iBaseDao.getValueByKey(medicalRecallDetail.getRecall().getHospitalId(), medicalRecallDetail.getRecall().getType());
			medicalRecallDetail.setrType(keyValue.getKeyValue());
			
			// 单位名称
			MedicalKeyValue unitkeyValue = this.iBaseDao.getValueByKey(medicalRecallDetail.getMedicine().getHospitalId(), medicalRecallDetail.getMedicine().getUnit());
			medicalRecallDetail.setMedicineUnit(unitkeyValue.getKeyValue());
			
		}
		page.setResult(list);
		return page;
	}

}
